home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / bash_114.zip / bash-1.14.2 / builtins / set.def < prev    next >
Encoding:
Text File  |  1994-04-16  |  14.2 KB  |  525 lines

  1. This file is set.def, from which is created set.c.
  2. It implements the "set" and "unset" builtins in Bash.
  3.  
  4. Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
  5.  
  6. This file is part of GNU Bash, the Bourne Again SHell.
  7.  
  8. Bash is free software; you can redistribute it and/or modify it under
  9. the terms of the GNU General Public License as published by the Free
  10. Software Foundation; either version 1, or (at your option) any later
  11. version.
  12.  
  13. Bash is distributed in the hope that it will be useful, but WITHOUT ANY
  14. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  15. FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  16. for more details.
  17.  
  18. You should have received a copy of the GNU General Public License along
  19. with Bash; see the file COPYING.  If not, write to the Free Software
  20. Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  21.  
  22. $PRODUCES set.c
  23.  
  24. #include <stdio.h>
  25. #include "../shell.h"
  26. #include "../flags.h"
  27.  
  28. #include "bashgetopt.h"
  29.  
  30. extern int interactive;
  31. extern int noclobber, no_brace_expansion, posixly_correct;
  32. #if defined (READLINE)
  33. extern int rl_editing_mode, no_line_editing;
  34. #endif /* READLINE */
  35.  
  36. #define USAGE_STRING "set [--abefhknotuvxldHCP] [-o option] [arg ...]"
  37.  
  38. $BUILTIN set
  39. $FUNCTION set_builtin
  40. $SHORT_DOC set [--abefhknotuvxldHCP] [-o option] [arg ...]
  41.     -a  Mark variables which are modified or created for export.
  42.     -b  Notify of job termination immediately.
  43.     -e  Exit immediately if a command exits with a non-zero status.
  44.     -f  Disable file name generation (globbing).
  45.     -h  Locate and remember function commands as functions are
  46.         defined.  Function commands are normally looked up when
  47.         the function is executed.
  48.     -i  Force the shell to be an "interactive" one.  Interactive shells
  49.         always read `~/.bashrc' on startup.
  50.     -k  All keyword arguments are placed in the environment for a
  51.         command, not just those that precede the command name.
  52.     -m  Job control is enabled.
  53.     -n  Read commands but do not execute them.
  54.     -o option-name
  55.         Set the variable corresponding to option-name:
  56.             allexport    same as -a
  57.             braceexpand  the shell will perform brace expansion
  58. #if defined (READLINE)
  59.             emacs        use an emacs-style line editing interface
  60. #endif /* READLINE */
  61.             errexit      same as -e
  62.             histexpand   same as -H
  63.             ignoreeof    the shell will not exit upon reading EOF
  64.             interactive-comments
  65.                          allow comments to appear in interactive commands
  66.             monitor      same as -m
  67.             noclobber    disallow redirection to existing files
  68.             noexec       same as -n
  69.             noglob       same as -f
  70.             nohash       same as -d
  71.             notify       save as -b
  72.             nounset      same as -u
  73.         physical     same as -P
  74.         posix        change the behavior of bash where the default
  75.              operation differs from the 1003.2 standard to
  76.              match the standard
  77.         privileged   same as -p
  78.             verbose      same as -v
  79. #if defined (READLINE)
  80.             vi           use a vi-style line editing interface
  81. #endif /* READLINE */
  82.             xtrace       same as -x
  83.     -p  Turned on whenever the real and effective user ids do not match.
  84.         Disables processing of the $ENV file and importing of shell
  85.         functions.  Turning this option off causes the effective uid and
  86.     gid to be set to the real uid and gid.
  87.     -t  Exit after reading and executing one command.
  88.     -u  Treat unset variables as an error when substituting.
  89.     -v  Print shell input lines as they are read.
  90.     -x  Print commands and their arguments as they are executed.
  91.     -l  Save and restore the binding of the NAME in a FOR command.
  92.     -d  Disable the hashing of commands that are looked up for execution.
  93.         Normally, commands are remembered in a hash table, and once
  94.         found, do not have to be looked up again.
  95. #if defined (BANG_HISTORY)
  96.     -H  Enable ! style history substitution.  This flag is on
  97.         by default.
  98. #endif /* BANG_HISTORY */
  99.     -C  If set, disallow existing regular files to be overwritten
  100.         by redirection of output.
  101.     -P  If set, do not follow symbolic links when executing commands
  102.         such as cd which change the current directory.
  103.  
  104. Using + rather than - causes these flags to be turned off.  The
  105. flags can also be used upon invocation of the shell.  The current
  106. set of flags may be found in $-.  The remaining n ARGs are positional
  107. parameters and are assigned, in order, to $1, $2, .. $n.  If no
  108. ARGs are given, all shell variables are printed.
  109. $END
  110.  
  111. /* An a-list used to match long options for set -o to the corresponding
  112.    option letter. */
  113. struct {
  114.   char *name;
  115.   int letter;
  116. } o_options[] = {
  117.   { "allexport",  'a' },
  118.   { "errexit",      'e' },
  119.   { "histexpand", 'H' },
  120.   { "monitor",      'm' },
  121.   { "noexec",      'n' },
  122.   { "noglob",      'f' },
  123.   { "nohash",      'd' },
  124. #if defined (JOB_CONTROL)
  125.   { "notify",      'b' },
  126. #endif /* JOB_CONTROL */
  127.   {"nounset",      'u' },
  128.   {"physical",    'P' },
  129.   {"privileged",  'p' },
  130.   {"verbose",      'v' },
  131.   {"xtrace",      'x' },
  132.   {(char *)NULL, 0},
  133. };
  134.  
  135. #define MINUS_O_FORMAT "%-15s\t%s\n"
  136.  
  137. void
  138. list_minus_o_opts ()
  139. {
  140.   register int    i;
  141.   char *on = "on", *off = "off";
  142.  
  143.   printf (MINUS_O_FORMAT, "braceexpand", (no_brace_expansion == 0) ? on : off);
  144.   printf (MINUS_O_FORMAT, "noclobber", (noclobber == 1) ? on : off);
  145.  
  146.   if (find_variable ("ignoreeof") || find_variable ("IGNOREEOF"))
  147.     printf (MINUS_O_FORMAT, "ignoreeof", on);
  148.   else
  149.     printf (MINUS_O_FORMAT, "ignoreeof", off);
  150.  
  151.   printf (MINUS_O_FORMAT, "interactive-comments",
  152.       interactive_comments ? on : off);
  153.  
  154.   printf (MINUS_O_FORMAT, "posix", posixly_correct ? on : off);
  155.  
  156. #if defined (READLINE)
  157.   if (no_line_editing)
  158.     {
  159.       printf (MINUS_O_FORMAT, "emacs", off);
  160.       printf (MINUS_O_FORMAT, "vi", off);
  161.     }
  162.   else
  163.     {
  164.       /* Magic.  This code `knows' how readline handles rl_editing_mode. */
  165.       printf (MINUS_O_FORMAT, "emacs", (rl_editing_mode == 1) ? on : off);
  166.       printf (MINUS_O_FORMAT, "vi", (rl_editing_mode == 0) ? on : off);
  167.     }
  168. #endif /* READLINE */
  169.  
  170.   for (i = 0; o_options[i].name; i++)
  171.     {
  172.       int *on_or_off, zero = 0;
  173.  
  174.       on_or_off = find_flag (o_options[i].letter);
  175.       if (on_or_off == FLAG_UNKNOWN)
  176.     on_or_off = &zero;
  177.       printf (MINUS_O_FORMAT, o_options[i].name, (*on_or_off == 1) ? on : off);
  178.     }
  179. }
  180.  
  181. set_minus_o_option (on_or_off, option_name)
  182.      int on_or_off;
  183.      char *option_name;
  184. {
  185.   int option_char = -1;
  186.  
  187.   if (STREQ (option_name, "braceexpand"))
  188.     {
  189.       if (on_or_off == FLAG_ON)
  190.     no_brace_expansion = 0;
  191.       else
  192.     no_brace_expansion = 1;
  193.     }
  194.   else if (STREQ (option_name, "noclobber"))
  195.     {
  196.       if (on_or_off == FLAG_ON)
  197.     bind_variable ("noclobber", "");
  198.       else
  199.     unbind_variable ("noclobber");
  200.       stupidly_hack_special_variables ("noclobber");
  201.     }
  202.   else if (STREQ (option_name, "ignoreeof"))
  203.     {
  204.       unbind_variable ("ignoreeof");
  205.       unbind_variable ("IGNOREEOF");
  206.       if (on_or_off == FLAG_ON)
  207.     bind_variable ("IGNOREEOF", "10");
  208.       stupidly_hack_special_variables ("IGNOREEOF");
  209.     }
  210.   
  211. #if defined (READLINE)
  212.   else if ((STREQ (option_name, "emacs")) || (STREQ (option_name, "vi")))
  213.     {
  214.       if (on_or_off == FLAG_ON)
  215.     {
  216.       rl_variable_bind ("editing-mode", option_name);
  217.  
  218.       if (interactive)
  219.         with_input_from_stdin ();
  220.       no_line_editing = 0;
  221.     }
  222.       else
  223.     {
  224.       int isemacs = (rl_editing_mode == 1);
  225.       if ((isemacs && STREQ (option_name, "emacs")) ||
  226.           (!isemacs && STREQ (option_name, "vi")))
  227.         {
  228.           if (interactive)
  229.         with_input_from_stream (stdin, "stdin");
  230.           no_line_editing = 1;
  231.         }
  232.       else
  233.         builtin_error ("not in %s editing mode", option_name);
  234.     }
  235.     }
  236. #endif /* READLINE */
  237.   else if (STREQ (option_name, "interactive-comments"))
  238.     interactive_comments = (on_or_off == FLAG_ON);
  239.   else if (STREQ (option_name, "posix"))
  240.     {
  241.       posixly_correct = (on_or_off == FLAG_ON);
  242.       unbind_variable ("POSIXLY_CORRECT");
  243.       unbind_variable ("POSIX_PEDANTIC");
  244.       if (on_or_off == FLAG_ON)
  245.     {
  246.       bind_variable ("POSIXLY_CORRECT", "");
  247.       stupidly_hack_special_variables ("POSIXLY_CORRECT");
  248.     }
  249.     }
  250.   else
  251.     {
  252.       register int i;
  253.       for (i = 0; o_options[i].name; i++)
  254.     {
  255.       if (STREQ (option_name, o_options[i].name))
  256.         {
  257.           option_char = o_options[i].letter;
  258.           break;
  259.         }
  260.     }
  261.       if (option_char == -1)
  262.     {
  263.       builtin_error ("%s: unknown option name", option_name);
  264.       return (EXECUTION_FAILURE);
  265.     }
  266.       if (change_flag (option_char, on_or_off) == FLAG_ERROR)
  267.     {
  268.       bad_option (option_name);
  269.       return (EXECUTION_FAILURE);
  270.     }
  271.     }
  272.   return (EXECUTION_SUCCESS);
  273. }
  274.  
  275. /* Set some flags from the word values in the input list.  If LIST is empty,
  276.    then print out the values of the variables instead.  If LIST contains
  277.    non-flags, then set $1 - $9 to the successive words of LIST. */
  278. set_builtin (list)
  279.      WORD_LIST *list;
  280. {
  281.   int on_or_off, flag_name, force_assignment = 0;
  282.  
  283.   if (!list)
  284.     {
  285.       SHELL_VAR **vars;
  286.  
  287.       vars = all_shell_variables ();
  288.       if (vars)
  289.     {
  290.       print_var_list (vars);
  291.       free (vars);
  292.     }
  293.  
  294.       vars = all_shell_functions ();
  295.       if (vars)
  296.     {
  297.       print_var_list (vars);
  298.       free (vars);
  299.     }
  300.  
  301.       return (EXECUTION_SUCCESS);
  302.     }
  303.  
  304.   /* Check validity of flag arguments. */
  305.   if (*list->word->word == '-' || *list->word->word == '+')
  306.     {
  307.       register char *arg;
  308.       WORD_LIST *save_list = list;
  309.  
  310.       while (list && (arg = list->word->word))
  311.     {
  312.       char c;
  313.  
  314.       if (arg[0] != '-' && arg[0] != '+')
  315.         break;
  316.  
  317.       /* `-' or `--' signifies end of flag arguments. */
  318.       if (arg[0] == '-' &&
  319.           (!arg[1] || (arg[1] == '-' && !arg[2])))
  320.         break;
  321.  
  322.       while (c = *++arg)
  323.         {
  324.           if (find_flag (c) == FLAG_UNKNOWN && c != 'o')
  325.         {
  326.           char s[2];
  327.           s[0] = c; s[1] = '\0';
  328.           bad_option (s);
  329.           if (c == '?')
  330.             printf ("usage: %s\n", USAGE_STRING);
  331.           return (c == '?' ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
  332.         }
  333.         }
  334.       list = list->next;
  335.     }
  336.       list = save_list;
  337.     }
  338.  
  339.   /* Do the set command.  While the list consists of words starting with
  340.      '-' or '+' treat them as flags, otherwise, start assigning them to
  341.      $1 ... $n. */
  342.   while (list)
  343.     {
  344.       char *string = list->word->word;
  345.  
  346.       /* If the argument is `--' or `-' then signal the end of the list
  347.      and remember the remaining arguments. */
  348.       if (string[0] == '-' && (!string[1] || (string[1] == '-' && !string[2])))
  349.     {
  350.       list = list->next;
  351.  
  352.       /* `set --' unsets the positional parameters. */
  353.       if (string[1] == '-')
  354.         force_assignment = 1;
  355.  
  356.       /* Until told differently, the old shell behaviour of
  357.          `set - [arg ...]' being equivalent to `set +xv [arg ...]'
  358.          stands.  Posix.2 says the behaviour is marked as obsolescent. */
  359.       else
  360.         {
  361.           change_flag ('x', '+');
  362.           change_flag ('v', '+');
  363.         }
  364.  
  365.       break;
  366.     }
  367.  
  368.       if ((on_or_off = *string) &&
  369.       (on_or_off == '-' || on_or_off == '+'))
  370.     {
  371.       int i = 1;
  372.       while (flag_name = string[i++])
  373.         {
  374.           if (flag_name == '?')
  375.         {
  376.           printf ("usage: %s\n", USAGE_STRING);
  377.           return (EXECUTION_SUCCESS);
  378.         }
  379.           else if (flag_name == 'o') /* -+o option-name */
  380.         {
  381.           char *option_name;
  382.           WORD_LIST *opt;
  383.  
  384.           opt = list->next;
  385.  
  386.           if (!opt)
  387.             {
  388.               list_minus_o_opts ();
  389.               continue;
  390.             }
  391.  
  392.           option_name = opt->word->word;
  393.  
  394.           if (!option_name || !*option_name || (*option_name == '-'))
  395.             {
  396.               list_minus_o_opts ();
  397.               continue;
  398.             }
  399.           list = list->next; /* Skip over option name. */
  400.  
  401.           if (set_minus_o_option (on_or_off, option_name) != EXECUTION_SUCCESS)
  402.             return (EXECUTION_FAILURE);
  403.         }
  404.           else
  405.         {
  406.           if (change_flag (flag_name, on_or_off) == FLAG_ERROR)
  407.             {
  408.               char opt[3];
  409.               opt[0] = on_or_off;
  410.               opt[1] = flag_name;
  411.               opt[2] = '\0';
  412.               bad_option (opt);
  413.               return (EXECUTION_FAILURE);
  414.             }
  415.         }
  416.         }
  417.     }
  418.       else
  419.     {
  420.       break;
  421.     }
  422.       list = list->next;
  423.     }
  424.  
  425.   /* Assigning $1 ... $n */
  426.   if (list || force_assignment)
  427.     remember_args (list, 1);
  428.   return (EXECUTION_SUCCESS);
  429. }
  430.  
  431. $BUILTIN unset
  432. $FUNCTION unset_builtin
  433. $SHORT_DOC unset [-f] [-v] [name ...]
  434. For each NAME, remove the corresponding variable or function.  Given
  435. the `-v', unset will only act on variables.  Given the `-f' flag,
  436. unset will only act on functions.  With neither flag, unset first
  437. tries to unset a variable, and if that fails, then tries to unset a
  438. function.  Some variables (such as PATH and IFS) cannot be unset; also
  439. see readonly.
  440. $END
  441.  
  442. unset_builtin (list)
  443.   WORD_LIST *list;
  444. {
  445.   int unset_function = 0, unset_variable = 0, opt;
  446.   int any_failed = 0;
  447.   char *name;
  448.  
  449.   reset_internal_getopt ();
  450.   while ((opt = internal_getopt (list, "fv")) != -1)
  451.     {
  452.       switch (opt)
  453.     {
  454.     case 'f':
  455.       unset_function = 1;
  456.       break;
  457.     case 'v':
  458.       unset_variable = 1;
  459.       break;
  460.     default:
  461.       return (EXECUTION_FAILURE);
  462.     }
  463.     }
  464.  
  465.   list = loptend;
  466.  
  467.   if (unset_function && unset_variable)
  468.     {
  469.       builtin_error ("cannot simultaneously unset a function and a variable");
  470.       return (EXECUTION_FAILURE);
  471.     }
  472.  
  473.   while (list)
  474.     {
  475.       name = list->word->word;
  476.  
  477.       if (!unset_function &&
  478.       find_name_in_list (name, non_unsettable_vars) > -1)
  479.     {
  480.       builtin_error ("%s: cannot unset", name);
  481.       any_failed++;
  482.     }
  483.       else
  484.     {
  485.       SHELL_VAR *var;
  486.       int tem;
  487.  
  488.       var = unset_function ? find_function (name) : find_variable (name);
  489.  
  490.       /* Posix.2 says that unsetting readonly variables is an error. */
  491.       if (var && readonly_p (var))
  492.         {
  493.           builtin_error ("%s: cannot unset: readonly %s",
  494.                  name, unset_function ? "function" : "variable");
  495.           any_failed++;
  496.           list = list->next;
  497.           continue;
  498.         }
  499.  
  500.       /* Unless the -f option is supplied, the name refers to a
  501.          variable. */
  502.       tem = makunbound
  503.         (name, unset_function ? shell_functions : shell_variables);
  504.  
  505.       /* This is what Posix.2 draft 11+ says.  ``If neither -f nor -v
  506.          is specified, the name refers to a variable; if a variable by
  507.          that name does not exist, a function by that name, if any,
  508.          shall be unset.'' */
  509.       if ((tem == -1) && !unset_function && !unset_variable)
  510.         tem = makunbound (name, shell_functions);
  511.  
  512.       if (tem == -1)
  513.         any_failed++;
  514.       else if (!unset_function)
  515.         stupidly_hack_special_variables (name);
  516.     }
  517.       list = list->next;
  518.     }
  519.  
  520.   if (any_failed)
  521.     return (EXECUTION_FAILURE);
  522.   else
  523.     return (EXECUTION_SUCCESS);
  524. }
  525.